package edu.uoc.tdp.pac3.server;

import java.rmi.*;
import java.util.*;
import java.sql.*;

// imports del projecte
import edu.uoc.tdp.pac3.common.Acreditacio;
import edu.uoc.tdp.pac3.common.Empleat;
import edu.uoc.tdp.pac3.common.Empresa;
import edu.uoc.tdp.pac3.common.EstatEvent;
import edu.uoc.tdp.pac3.common.Event;
import edu.uoc.tdp.pac3.server.*;

/**
/* Classe que implementa la interficie que dona servei remotament 
 * 
 */
public class RemotImpl extends java.rmi.server.UnicastRemoteObject implements RemoteInterface {

	private static final long serialVersionUID = 1L;
	/** Objecte gestor de disc empleat */
	private GestorDiscEmpleat gde;
	/** Objecte gestor de disc acreditacio */
	private GestorDiscAcreditacio gda;
	/** Objecte gestor de disc empresa */
	private GestorDiscEmpresa gdm;
	/** Objecte gestor connexio disc */
	private GestorConnexioDisc gcd;
	/** Objecte gestor Event **/
	private GestorDiscEvent gdev;
	
	/**
	 * Constructor amb una parametre de la classe RemotImpl
	 * Crea una instancia de la classe que implementa RemoteInterface
	 * Inicialitza els gestors de disc per a accedir a les dades
	 * {pre: S'ha establert una connexio remota entre el client i el servidor}
	 * {post: Torna una instancia de la classe RemotImpl}
	 * @throws RemoteException
	 */
	public RemotImpl(GestorConnexioDisc pGcd) throws RemoteException {
		gde = new GestorDiscEmpleat(pGcd);
		gda = new GestorDiscAcreditacio(pGcd);
		gdm = new GestorDiscEmpresa(pGcd);
		gdev = new GestorDiscEvent(pGcd);
		gcd = pGcd;
	}

	/**
	 * Metode per a donar d'alta un nou empleat
	 * Implementa la interficie del mateix metode del servidor
	 * {pre: el servidor remot esta en servei}
	 * {post: s'ha donat d'alta un nou empleat}
	 * @param pEmpleat es el nou empleat
	 * @throws RemoteException  
	 * 
	 */
	public void altaNouEmpleat(Empleat pEmpleat) throws RemoteException {
		
		try{
			gde.introduirEmpleat(pEmpleat);
		}catch (SQLException sqle){
			try{
				gcd.getConexion().rollback(); //Desfem qualsevol canvi
				gcd.getConexion().setAutoCommit(true); //Retorna el sistema al commit automatic
			}catch (SQLException sqlr){
				throw new RemoteException("", sqlr); //Anidem l'excepcio sql
			}catch (Exception e){
				throw new RemoteException("", e); //Anidem l'excepcio
			}
		}catch (Exception e) {
			try{
				gcd.getConexion().rollback(); //Desfem qualsevol canvi
				gcd.getConexion().setAutoCommit(true); //Retorna el sistema al commit automatic
			}catch (SQLException sqlr){
				throw new RemoteException("", sqlr); //Anidem l'excepcio sql
			}finally{
				gcd.cerrarSentencia(); //Tanquem la sentencia
			}
		}
	}

	/**
	 * Metode per a donar d'alta una nova acreditacio
	 * Implementa la interficie del mateix metode del servidor
	 * {pre: el servidor remot esta en servei}
	 * {post: s'ha donat d'alta un nou empleat}
	 * @param pEmpleat es el nou empleat
	 * @throws RemoteException  
	 * 
	 */
	public void altaNovaAcreditacio(Acreditacio pAcreditacio) throws RemoteException {
		try{
			gda.introduirAcreditacio(pAcreditacio);
		}catch (SQLException sqle){
			try{
				gcd.getConexion().rollback(); //Desfem qualsevol canvi
				gcd.getConexion().setAutoCommit(true); //Retorna el sistema al commit automatic
			}catch (SQLException sqlr){
				throw new RemoteException("", sqlr); //Anidem l'excepcio sql
			}catch (Exception e){
				throw new RemoteException("", e); //Anidem l'excepcio
			}
		}catch (Exception e) {
			try{
				gcd.getConexion().rollback(); //Desfem qualsevol canvi
				gcd.getConexion().setAutoCommit(true); //Retorna el sistema al commit automatic
			}catch (SQLException sqlr){
				throw new RemoteException("", sqlr); //Anidem l'excepcio sql
			}finally{
				gcd.cerrarSentencia(); //Tanquem la sentencia
			}
		}
	}		
	
	/**
	 * Metode que obte la llista de tots els events
	 * Implementa la interficie del mateix metode del servidor
	 * @throws RemoteException  
	 * 
	 */
	public Event[] obtenirLListaEvents() throws RemoteException {
		// Obtenir llista Events
		Vector<Event> v3 = null;
		Event[] eve = null;
		try{
			v3 = gdev.obtenirEvents();
			eve = new Event[v3.size()];
			for (int i = 0; i< eve.length; i++){
				eve[i] = (Event)v3.elementAt(i);
			}
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return eve;
	}

	/**
	 * Metode que obte la llista de tots els empleats
	 * Implementa la interficie del mateix metode del servidor
	 * @throws RemoteException  
	 * 
	 */
	public Empleat[] obtenirLListaEmpleats() throws RemoteException {
		Vector<Empleat> v2 = null;
		Empleat[] emple = null;
		
		try{
			v2 = gde.obtenirEmpleats();
			emple = new Empleat[v2.size()];
			for (int i = 0; i < emple.length; i++){
				emple[i] = (Empleat)v2.elementAt(i);
			}
		} catch (Exception e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return emple;
	}
	
	/**
	 * Metode que obte la llista de totes les empreses
	 * Implementa la interficie del mateix metode del servidor
	 * @throws RemoteException  
	 * 
	 */	
	public Empresa[] obtenirLListaEmpreses() throws RemoteException {

		Vector<Empresa> v = null;
		Empresa[] emp =null;
		
		try {
			v = gdm.obtenirEmpreses();
			emp = new Empresa[v.size()];
		    for (int i=0; i < emp.length; i++)
		    {
		      emp[i] = (Empresa)v.elementAt(i);
		    }
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return emp;
	}

	/**
	 * Metode que obte la llista d'acreditacions d'un empleat
	 * Implementa la interficie del mateix metode del servidor
	 * @throws RemoteException  
	 * 
	 */	
	public Acreditacio[] obtenirAcreditacionsEmpleat(Empleat pEmpleat) throws RemoteException {

		Vector<Acreditacio> v = null;
		Acreditacio[] acr =null;
		
		try {
			v = gda.obtenirAcreditacionsEmpleat(pEmpleat);
			acr = new Acreditacio[v.size()];
		    for (int i=0; i < acr.length; i++)
		    {
		      acr[i] = (Acreditacio)v.elementAt(i);
		    }
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return acr;
	}
	
	/**
	 * Metode que obte la llista d'estats dels events
	 * Implementa la interficie del mateix metode del servidor
	 * @throws RemoteException  
	 * 
	 */	
	public EstatEvent[] obtenirEstatEvents(Event event) throws RemoteException {
		// Obtenir llista Events
		Vector<EstatEvent> v = null;
		EstatEvent[] estatEvent = null;
		try{
			v = gdev.obtenirEstatEvents(event);
			estatEvent = new EstatEvent[v.size()];
			for (int i = 0; i< estatEvent.length; i++){
				estatEvent[i] = (EstatEvent)v.elementAt(i);
			}
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return estatEvent;
	}
}
